/*     */ package handling.netty;
/*     */
/*     */ import client.MapleClient;
/*     */ import configs.OpcodeConfig;
/*     */ import configs.ServerConfig;
/*     */ import handling.MapleServerHandler;
/*     */ import handling.ServerType;
/*     */ import handling.opcode.SendPacketOpcode;
/*     */ import io.netty.buffer.ByteBuf;
/*     */ import io.netty.channel.ChannelHandlerContext;
/*     */ import io.netty.handler.codec.MessageToByteEncoder;
/*     */ import java.util.concurrent.locks.Lock;
/*     */ import org.apache.logging.log4j.LogManager;
/*     */ import org.apache.logging.log4j.Logger;
/*     */ import tools.HexTool;
/*     */ import tools.MapleAESOFB;
/*     */ import tools.StringUtil;
/*     */ import tools.data.input.ByteArrayByteStream;
/*     */ import tools.data.input.ByteInputStream;
/*     */ import tools.data.input.GenericLittleEndianAccessor;
/*     */
/*     */ public class MaplePacketEncoder extends MessageToByteEncoder<Object> {
    /*  27 */   private static final Logger log = LogManager.getLogger("DebugWindows");
    /*     */
    /*     */   private ServerType type;
    /*     */
    /*     */   MaplePacketEncoder(ServerType type) {
        /*  32 */     this.type = type;
        /*     */   }
    /*     */

    protected void encode(ChannelHandlerContext ctx, Object message, ByteBuf buffer) throws Exception {
        MapleClient client = (MapleClient)ctx.channel().attr(MapleClient.CLIENT_KEY).get();
        if (client != null) {
            MapleAESOFB send_crypto = client.getSendCrypto();
            byte[] input = (byte[])((byte[])message);
            int packetLen = input.length;
            int pHeader = this.readFirstShort(input);
            String pHeaderStr = Integer.toHexString(pHeader).toUpperCase();
            pHeaderStr = StringUtil.getLeftPaddedStr(pHeaderStr, '0', 4);
            String op = this.lookupRecv(pHeader);
            String Send = "Send " + op + " [" + pHeaderStr + "] (" + packetLen + ")";
            Send = Send + (client.getPlayer() != null ? " Recv to : " + client.getPlayer().getName() + "\r\n" : "\r\n");
            String RecvTo = Send + HexTool.toString(input) + "\r\n" + HexTool.toStringFromAscii(input);
            if (ServerConfig.DEBUG_MODE && !OpcodeConfig.isblock(op, true)) {
                MapleServerHandler.AllPacketLog.info(RecvTo);
            }

            if (ServerConfig.DEBUG_MODE && op.equals("GIVE_BUFF") || op.equals("CANCEL_BUFF")) {
                MapleServerHandler.BuffPacketLog.trace("\r\n" + RecvTo);
            }

            byte[] unencrypted = new byte[input.length];
            System.arraycopy(input, 0, unencrypted, 0, input.length);
            byte[] ret;
            if (input.length >= 65280) {
                ret = new byte[unencrypted.length + 8];
            } else {
                ret = new byte[unencrypted.length + 4];
            }

            Lock mutex = client.getLock();
            mutex.lock();

            try {
                byte[] header = send_crypto.getPacketHeaderN(unencrypted.length);
                if (!this.type.equals(ServerType.登录服务器)) {
                    MapleCustomEncryption.Encrypt(unencrypted, send_crypto.getIv());
                    send_crypto.updateIv();
                } else {
                    send_crypto.crypt(unencrypted);
                }

                if (input.length >= 65280) {
                    System.arraycopy(header, 0, ret, 0, 8);
                    System.arraycopy(unencrypted, 0, ret, 8, unencrypted.length);
                } else {
                    System.arraycopy(header, 0, ret, 0, 4);
                    System.arraycopy(unencrypted, 0, ret, 4, unencrypted.length);
                }

                buffer.writeBytes(ret);
            } finally {
                mutex.unlock();
            }
        } else {
            buffer.writeBytes((byte[])((byte[])message));
        }

    }


    /*     */   private String lookupRecv(int val) {
        /* 103 */     for (SendPacketOpcode op : SendPacketOpcode.values()) {
            /* 104 */       if (op.getValue() == val)
                /* 105 */         return op.name();
            /*     */     }
        /* 108 */     return "UNKNOWN";
        /*     */   }
    /*     */
    /*     */   private int readFirstShort(byte[] arr) {
        /* 112 */     return (new GenericLittleEndianAccessor((ByteInputStream)new ByteArrayByteStream(arr))).readShort();
        /*     */   }
    /*     */ }

